﻿
Imports System.Runtime.CompilerServices
Imports osi.root.connector

Public Module _weak_pointer
    Public Function make_weak_pointer(Of T)(ByVal i As T) As weak_pointer(Of T)
        Return New weak_pointer(Of T)(i)
    End Function

    Public Function make_weak_pointers(Of T)(ByVal ParamArray i() As T) As weak_pointer(Of T)()
        Dim r() As weak_pointer(Of T) = Nothing
        ReDim r(array_size(i) - 1)
        For j As Int32 = 0 To array_size(i) - 1
            r(j) = make_weak_pointer(i(j))
        Next
        Return r
    End Function

    <Extension()> Public Sub renew(Of T)(ByRef i As weak_pointer(Of T))
        If i Is Nothing Then
            i = New weak_pointer(Of T)()
        Else
            i.clear()
        End If
    End Sub
End Module

Public Class weak_pointer(Of T)
    Inherits _pointer(Of T)
    Implements IComparable(Of weak_pointer(Of T))

    Private p As WeakReference '= Nothing
    'do not write any initialization commands in the defination.
    'since the base class ctor will be called first,
    'if the base class has tried to set some value by calling overrides functions, it will fail.

    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal i As T)
        MyBase.New(i)
    End Sub

    Public Sub New(ByVal i As _pointer(Of T))
        MyBase.New(i)
    End Sub

    Public NotOverridable Overrides Sub clear()
        p = Nothing
    End Sub

    Public Overloads Function [get](ByRef o As T) As Boolean
        If p Is Nothing Then
            Return False
        Else
            o = cast(Of T)(p.Target())
            Return p.IsAlive()
        End If
    End Function

    Public Function alive() As Boolean
        Return Not p Is Nothing AndAlso p.IsAlive()
    End Function

    Public NotOverridable Overrides Function [get]() As T
        Dim o As T = Nothing
        Return If([get](o), o, Nothing)
    End Function

    Public NotOverridable Overrides Sub [set](ByVal i As T)
        p = New WeakReference(i)
    End Sub

    Protected Overrides Sub Finalize()
        GC.KeepAlive(p)
        MyBase.Finalize()
    End Sub

    Public Overloads Function CompareTo(ByVal other As weak_pointer(Of T)) As Int32 _
                                       Implements IComparable(Of weak_pointer(Of T)).CompareTo
        Return MyBase.CompareTo(other)
    End Function
End Class
